//
//  UIView+RBAdd.m
//  GXSign
//
//  Created by 蓝其 on 16/11/15.
//  Copyright © 2016年 GX. All rights reserved.
//

#import "UIView+RBAdd.h"
#import "Masonry.h"
#import "MBProgressHUD.h"
#import "UIView+YYAdd.h"
#import <YYCategories/NSObject+YYAdd.h>
#import "RBThemeConfig.h"
#import <POP.h>
#import "RBDefine.h"
#import <objc/objc.h>
#import <objc/runtime.h>

char *const RB_PLACE_HOLDER_BLOCK_KEY = "RB_PLACE_HOLDER_BLOCK_KEY";
static char *const RB_MEDIA_RESPONSE_AREA_KEY = "RB_MEDIA_RESPONSE_AREA_KEY";

static char *const RB_VIEW_CORNER_KEY = "RB_VIEW_CORNER_KEY";
static char *const RB_VIEW_RADIUS_KEY = "RB_VIEW_RADIUS_KEY";

@interface RBBackBtn: UIButton
@end
@implementation RBBackBtn
@end

@implementation UIView(RBAdd)

- (void)rbSetCornerRadius: (CGFloat)value
{
    self.layer.cornerRadius = value;
    self.clipsToBounds = YES;
}

- (void)rbSetCorner:(UIRectCorner)corner radius:(CGFloat)radius
{
    if (radius)
    {
        objc_setAssociatedObject(self, RB_VIEW_CORNER_KEY, [NSNumber numberWithInteger:corner], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        objc_setAssociatedObject(self, RB_VIEW_RADIUS_KEY, [NSNumber numberWithFloat:radius], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    }
    else
    {
        objc_setAssociatedObject(self, RB_VIEW_CORNER_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        objc_setAssociatedObject(self, RB_VIEW_RADIUS_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        
        self.layer.mask = nil;
    }
}

- (void)setRounderWithRectCorner:(UIRectCorner)rectCorner radius:(CGFloat)radius
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:rectCorner cornerRadii:CGSizeMake(radius, radius)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;
}

- (void)rbSetBorderWitdh: (CGFloat)width borderColor: (UIColor *)color
{
    self.layer.borderWidth = width;
    self.layer.borderColor = color.CGColor;
}

- (void)rbAddTapGesWithTarget:(id)target action:(SEL)action
{
    self.userInteractionEnabled = YES;
    [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:target action:action]];
}

- (void)rbRemoveAllGes
{
    while (self.gestureRecognizers.count)
    {
        [self removeGestureRecognizer:self.gestureRecognizers.firstObject];
    }
}

- (UIColor *)borderColor
{
    return [UIColor colorWithCGColor:self.layer.borderColor];
}

- (void)setBorderColor:(UIColor *)borderColor
{
    self.layer.borderColor = borderColor.CGColor;
}

- (CGFloat)borderWidth
{
    return self.layer.borderWidth;
}

- (void)setBorderWidth:(CGFloat)borderWidth
{
    self.layer.borderWidth = borderWidth;
}

- (CGFloat)cornerRadius
{
    return self.layer.cornerRadius;
}

- (void)setCornerRadius:(CGFloat)cornerRadius
{
    self.layer.cornerRadius = cornerRadius;
    self.clipsToBounds = YES;
}

- (void)setExtendResponseAreaValue:(CGFloat)extendResponseAreaValue
{
    [self setResponseArea:UIEdgeInsetsMake(extendResponseAreaValue, extendResponseAreaValue, extendResponseAreaValue, extendResponseAreaValue)];
}

- (id)rbExData
{
    return objc_getAssociatedObject(self, "rbExData");
}

- (void)setRbExData:(id)rbExData
{
    objc_setAssociatedObject(self, "rbExData", rbExData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)hideSubViews
{
    for (UIView *subView in self.subviews)
    {
        subView.hidden = YES;
    }
}

- (void)showSubViews
{
    for (UIView *subView in self.subviews)
    {
        subView.hidden = NO;
    }
}

+ (instancetype)view
{
    return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil].lastObject;
}

+ (UIView *)blurView
{
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    return blurView;
}

+ (CAGradientLayer *)gradientLayerWithColors: (NSArray *)colors locations:(NSArray *)locations vertical: (BOOL)vertical
{
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.colors = ({
        NSMutableArray *arrayM = [NSMutableArray array];
        for (UIColor *color in colors)
        {
            [arrayM addObject:(__bridge id)color.CGColor];
        }
        arrayM;
    });
    gradientLayer.locations = locations.count? locations: ({
        NSMutableArray *arrayM = [NSMutableArray array];
        CGFloat slice = 1.0/(colors.count - 1);
        for (NSInteger i = 0; i < colors.count; i++)
        {
            [arrayM addObject:@(slice*i)];
        }
        arrayM;
    });
    if (vertical)
    {
        gradientLayer.startPoint = CGPointMake(0.5, 0);
        gradientLayer.endPoint = CGPointMake(0.5, 1);
    }
    else
    {
        gradientLayer.startPoint = CGPointMake(0, 0.5);
        gradientLayer.endPoint = CGPointMake(1, 0.5);
    }
    return gradientLayer;
}

+ (void)load
{
    [self swizzleInstanceMethod:@selector(swizzledPointInside:withEvent:) with:@selector(pointInside:withEvent:)];
    [self swizzleInstanceMethod:@selector(swizzleLayoutSubviews) with:@selector(layoutSubviews)];
}

- (void)swizzleLayoutSubviews
{
    [self swizzleLayoutSubviews];
    NSNumber *cornerValue = objc_getAssociatedObject(self, RB_VIEW_CORNER_KEY);
    NSNumber *radiusValue = objc_getAssociatedObject(self, RB_VIEW_RADIUS_KEY);
    if(cornerValue && radiusValue)
    {
        NSInteger corner = cornerValue.integerValue;
        CGFloat radius = radiusValue.floatValue;
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;
    }
}

- (void)setResponseArea:(UIEdgeInsets)area
{
    objc_setAssociatedObject(self, RB_MEDIA_RESPONSE_AREA_KEY, [NSValue valueWithUIEdgeInsets:area], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)extendResponseArea
{
    [self setResponseArea:UIEdgeInsetsMake(12, 12, 12, 12)];
}

- (BOOL)swizzledPointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    NSValue *value = objc_getAssociatedObject(self, RB_MEDIA_RESPONSE_AREA_KEY);
    if (value)
    {
        UIEdgeInsets insets = value.UIEdgeInsetsValue;
        CGFloat x = -insets.left;
        CGFloat y = -insets.top;
        CGFloat w = self.bounds.size.width + insets.left + insets.right;
        CGFloat h = self.bounds.size.height + insets.top + insets.bottom;
        CGRect frame = CGRectMake(x, y, w, h);
        return CGRectContainsPoint(frame, point);
    }
    else
    {
        return CGRectContainsPoint(self.bounds, point);
    }
}

- (void)addPriority:(NSInteger)add
{
    [self setContentHuggingPriority:UILayoutPriorityDefaultHigh + add forAxis:UILayoutConstraintAxisHorizontal];
    [self setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh + add forAxis:UILayoutConstraintAxisHorizontal];
}

- (void)addVPriority:(NSInteger)add
{
    [self setContentHuggingPriority:UILayoutPriorityDefaultHigh + add forAxis:UILayoutConstraintAxisVertical];
    [self setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh + add forAxis:UILayoutConstraintAxisVertical];
}

- (CGSize)esSize
{
    return [self systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}

- (CGSize)esSizeWithWidth: (CGFloat)width
{
    return [self systemLayoutSizeFittingSize:CGSizeMake(width, CGFLOAT_MAX)];
}

@end

@implementation UIView(RBHud)

- (void)showMBProgressWithText:(NSString *)text underView:(UIView *)view offsetY: (CGFloat)offsetY
{
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self animated:YES];
    hud.bezelView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
    hud.contentColor = [UIColor whiteColor];
    hud.mode = MBProgressHUDModeIndeterminate;
    hud.label.numberOfLines = 0;
    hud.label.text = text;
    hud.label.textColor = [UIColor whiteColor];
    if (view)
    {
        [self insertSubview:hud belowSubview:view];
    }
    if (offsetY)
    {
        hud.offset = CGPointMake(0, offsetY);
    }
}

- (void)showMBProgressWithText:(NSString *)text underView:(UIView *)view
{
    [self showMBProgressWithText:text underView:view offsetY:0];
}

- (void)showProgressWithText:(NSString *)text underView:(UIView *)view
{
    [self showMBProgressWithText:text underView:view];
}

- (void)showProgressWithText:(NSString *)text
{
    [self showProgressWithText:text underView:nil];
}

- (void)showProgressWithText: (NSString *)text offsetY:(CGFloat)offsetY
{
    [self showMBProgressWithText:text underView:nil offsetY:offsetY];
}

- (void)showMBTip:(NSString *)tip delay:(CGFloat)delayTime completion:(void (^)(void))block
{
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self animated:YES];
    hud.bezelView.backgroundColor = [UIColor blackColor];
    hud.mode = MBProgressHUDModeText;
    hud.label.numberOfLines = 0;
    hud.label.text = tip;
    hud.label.textColor = [UIColor whiteColor];
    __weak typeof(self) weak_self = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:weak_self animated:YES];
        if(block)
        {
            block();
        }
    });
}

- (void)showTip:(NSString *)tip delay:(CGFloat)delayTime completion:(void (^)(void))block
{
    [self showMBTip:tip delay:delayTime completion:block];
}

- (void)showTip:(NSString *)tip completion:(void (^)(void))block
{
    [self showTip:tip delay:1 completion:block];
}

- (void)hideHud
{
    [MBProgressHUD hideHUDForView:self animated:YES];
}

@end

@implementation UIView(RBBackBtn)

- (void)addBackBtnWithWidth: (CGFloat)width image: (UIImage *)image
{
    RBBackBtn *backBtn = [RBBackBtn new];
    [backBtn setImage:image forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:backBtn];
    if (image)
    {
        CGFloat arrorWidth = image.size.width;
        CGFloat leftPadding = 20;
        CGFloat rightPadding = width - arrorWidth - leftPadding;
        backBtn.imageEdgeInsets = UIEdgeInsetsMake(0, leftPadding, 0, rightPadding);
    }
    else
    {
        backBtn.backgroundColor = [UIColor blackColor];
        backBtn.showsTouchWhenHighlighted = YES;
    }
    [backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.bottom.mas_equalTo(0);
        make.width.mas_equalTo(width);
    }];
}

- (void)addBackBtn
{
    [self addBackBtnWithWidth:70 image:[UIImage imageNamed:@"backArror"]];
}

- (void)backButtonTapped: (id)sender
{
    [[self viewController].navigationController popViewControllerAnimated:YES];
}

- (UIButton *)getBackBtn
{
    for (UIView *subView in self.subviews)
    {
        if ([subView isKindOfClass:[RBBackBtn class]])
        {
            return (UIButton *)subView;
        }
    }
    return nil;
}

@end

@implementation UIView(RBPlaceHolder)

- (void)showPlaceHolder:(NSString *)placeHolder tapBlock:(void (^)(void))block
{
    [self showPlaceHolder:placeHolder textColor:nil top:0 tapBlock:block];
}

- (void)showPlaceHolder:(NSString *)placeHolder textColor:(UIColor *)textColor top:(CGFloat)top tapBlock:(void (^)(void))block
{
    [self setAssociateValue:block withKey:RB_PLACE_HOLDER_BLOCK_KEY];
    UIView *view = [UIView new];
    [view rbAddTapGesWithTarget:self action:@selector(placeHolderViewTapped)];
    view.userInteractionEnabled = block != nil;
    view.tag = 7858;
    [self addSubview:view];
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.mas_equalTo(0);
        make.width.mas_equalTo(self.mas_width);
        make.height.mas_equalTo(self.mas_height);
    }];
    
    UILabel *label = [UILabel new];
    label.text = placeHolder;
    [view addSubview:label];
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_equalTo(-15);
        if (top)
        {
            make.top.mas_equalTo(top);
        }
        else
        {
            make.top.mas_equalTo(15);
            make.bottom.mas_equalTo(-15);
        }
    }];
    label.textColor = textColor? textColor: [RBThemeConfig textBlackColor];
    label.font = [UIFont systemFontOfSize:13];
    label.numberOfLines = 0;
    label.textAlignment = NSTextAlignmentCenter;
}

- (void)placeHolderViewTapped
{
    void(^block)(void) = [self getAssociatedValueForKey: RB_PLACE_HOLDER_BLOCK_KEY];
    if (block)
    {
        block();
    }
}

- (void)hidePlaceHolder
{
    for (UIView *subView in self.subviews)
    {
        if (subView.tag == 7858)
        {
            [subView removeFromSuperview];
        }
    }
}

@end

@implementation UIView(Animation)

- (void)addShakeAnimation
{
    POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];
    double radius = M_PI/150;
    animation.fromValue = @(-radius);
    animation.toValue = @(radius);
    animation.repeatForever = YES;
    animation.autoreverses = YES;
    animation.beginTime = CACurrentMediaTime() + 0;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.additive = NO;
    animation.duration = 0.1;
    [self.layer pop_addAnimation:animation forKey:@"deleteShake"];
}

- (void)removeShakeAnimation
{
    [self.layer pop_removeAnimationForKey:@"deleteShake"];
    self.transform = CGAffineTransformIdentity;
}

- (void)addTapZoomAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    animation.values = @[@(1), @(1.5), @(1)];
    animation.duration = 0.3;
    animation.removedOnCompletion = YES;
    [self.layer addAnimation:animation forKey:@"addTapZoomAnimation"];
}

- (void)addTapMultipleZoomAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    animation.duration = 0.5;
    animation.values = @[@(1),
                         @(0.6),
                         @(1),
                         @(0.7),
                         @(1),
                         @(0.8),
                         @(1),
                         ];
    animation.removedOnCompletion = YES;
    [self.layer addAnimation:animation forKey:@"addTapMultipleZoomAnimation"];
}

- (void)addLittleZoomAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    animation.values = @[@(1), @(1.05), @(1)];
    animation.duration = 0.1;
    animation.removedOnCompletion = YES;
    [self.layer addAnimation:animation forKey:@"addTapZoomAnimation"];
}

- (void)addTapContinuousZoomAnimation
{
    CGFloat min = 0.85;
    CGFloat max = 1.2;
    CGFloat duration = 0.5;
    [UIView animateWithDuration:duration/2 animations:^{
        self.transform = CGAffineTransformMakeScale(min, min);
    } completion:^(BOOL finished) {
        POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
        animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(min, min)];
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(max, max)];
        animation.repeatForever = YES;
        animation.autoreverses = YES;
        animation.beginTime = CACurrentMediaTime() + 0;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        animation.additive = NO;
        animation.duration = duration;
        [self.layer pop_addAnimation:animation forKey:@"addTapContinuousZoomAnimation"];
    }];
}

- (void)removeTapContinuousZoomAnimation
{
    [self.layer pop_removeAnimationForKey:@"addTapContinuousZoomAnimation"];
    self.transform = CGAffineTransformIdentity;
}

@end
